package fem2.element;

import math2.MathUtilities;

import org.junit.Test;

import fem2.AbstractStructuralCrackDemo;
import fem2.Constraint;
import fem2.Debugger;
import fem2.Element;
import fem2.MaterialModel;
import fem2.Mesh;
import fem2.MeshPart;
import fem2.MeshUtilities;
import fem2.Model;
import fem2.PatchTestTet4;
import fem2.analysis.Analysis;
import fem2.analysis.NonlinearStaticManualAnalysis;
import fem2.element.crack_sda.SOSConstantJumpTetrahedraElement;
import fem2.enu.EchoLevelType;
import fem2.enu.State;
import fem2.material.StVenantKirchhoffMM;
import fem2.material.cohesive_law.CohesiveLaw;
import fem2.material.cohesive_law.Mode1LinearCohesiveLaw;

public class PatchTestSOSConstantJumpTetrahedraElement extends AbstractStructuralCrackDemo {

	public Mesh createMesh() {
		return new PatchTestTet4(0).createMesh();
	}

	@Override
	public MaterialModel createMaterial(Model m) {
		double E = 2;
		double nu = 0.3;
		double t = 1.0;
		State ss = State.THREE_DIMENSIONAL;
		return new StVenantKirchhoffMM(E, nu, t, 0, ss);
	}

	@Override
	public CohesiveLaw createCohesiveLaw(Model m) {
		double H = -1;
		double ft = 0.91;
		double km1 = 0.0;
		double km2 = 0.0;
		double Gf = -(ft * ft) / (2 * H);
		return new Mode1LinearCohesiveLaw(Gf, ft, km1, km2);
	}

	@Override
	public Element createElement(MeshPart mp, MaterialModel mm, CohesiveLaw cl) {
		SOSConstantJumpTetrahedraElement e = new SOSConstantJumpTetrahedraElement(mp, mm, cl);
		e.setEchoLevel(EchoLevelType.AUX4);
		return e;
	}

	@Override
	public Model createConditions(Model m) {
		Constraint c8 = new Constraint(false, false, false);
		Constraint c6 = new Constraint(false, true, false);
		Constraint c7 = new Constraint(false, false, true);
		Constraint c4 = new Constraint(false, true, true);

		double du = 1.0;
		c8.setValue(0, du);
		c6.setValue(0, du);
		c7.setValue(0, du);
		c4.setValue(0, du);

		MeshUtilities.seekNode(m.getMesh(), 1, 0, 0).setConstraint(c8);
		MeshUtilities.seekNode(m.getMesh(), 1, 1, 0).setConstraint(c6);
		MeshUtilities.seekNode(m.getMesh(), 1, 0, 1).setConstraint(c7);
		MeshUtilities.seekNode(m.getMesh(), 1, 1, 1).setConstraint(c4);

		return m;
	}

	@Override
	public void run(double[] lambda) {
		Model m = createModel();

		Analysis an = new NonlinearStaticManualAnalysis(m, lambda, lambda);
		an.getStrategy().setEchoLevel(EchoLevelType.OUTPUT, EchoLevelType.AUX1);

		// addObservers(m, an.getStrategy());

		an.run();

		postProcess(m);

		Debugger.warn("Analysis completed");
	}

	@Test
	public void test1() {
		AbstractStructuralCrackDemo demo = new PatchTestSOSConstantJumpTetrahedraElement();

		double[] lambda = MathUtilities.createLambdaArray(0.0, 0.1, 1);

		demo.run(lambda);
	}
}
